package zhoug.common.content;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;

import java.io.File;

import androidx.annotation.NonNull;
import zhoug.common.encrypt.IEncryptor;
import zhoug.logging.Logger;

/**
 * {@link SharedPreferences}的包装类
 * 支持数据加密
 *
 * @Author 35574
 * @Date 2021/7/28
 * @Description
 */
public class SharedPreferencesWrap {
    private static final String TAG = ">>>SharedPreferencesWrap";
    private SharedPreferences mSharedPreferences;
    /**
     * 是否启用数据加密
     */
    private boolean encryptEnable = true;


    private IEncryptor encryptor;


    public static SharedPreferencesWrap with(SharedPreferences sharedPreferences) {
        return new SharedPreferencesWrap(sharedPreferences);
    }

    /**
     * 根据名字获取SharedPreferences
     *
     * @param context
     * @param name
     * @return
     */
    public static SharedPreferencesWrap with(@NonNull Context context, @NonNull String name) {
        return new SharedPreferencesWrap(context.getSharedPreferences(name, Context.MODE_PRIVATE));
    }

    /**
     * 默认的SharedPreferences
     *
     * @param context
     * @return
     */
    public static SharedPreferencesWrap with(@NonNull Context context) {
        return new SharedPreferencesWrap(context.getSharedPreferences(context.getPackageName() + "_preferences", Context.MODE_PRIVATE));
    }


    public SharedPreferencesWrap(SharedPreferences sharedPreferences) {
        this.mSharedPreferences = sharedPreferences;
    }


    /**
     * 是否启用数据加密
     *
     * @param encryptEnable
     */
    public SharedPreferencesWrap setEncryptEnable(boolean encryptEnable) {
        this.encryptEnable = encryptEnable;
        return this;
    }

    /**
     * 数据加密
     *
     * @param IEncryptor
     */
    public void setEncryptor(IEncryptor IEncryptor) {
        this.encryptor = IEncryptor;
    }


    /**
     * 加密key
     *
     * @param key
     * @return
     */
    private String encryptKey(String key) {
        if (encryptor != null && encryptEnable && key != null && !key.isEmpty()) {
            try {
                return encryptor.encryptToBase64(key);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return key;
    }

    /**
     * 加密value
     *
     * @param value
     * @return
     */
    private String encryptValue(String value) {
        if (encryptor != null && encryptEnable && value != null && !value.isEmpty()) {
            try {
                return encryptor.encryptToBase64(value);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return value;
    }

    /**
     * 解密value
     *
     * @param value
     * @return
     */
    private String decryptValue(String value) {
        if (encryptor != null && encryptEnable && value != null && !value.isEmpty()) {
            try {
                return encryptor.decryptToString(value);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return value;
    }

    /**
     * 获取字符串
     *
     * @param key
     * @param defValue
     * @return
     */
    public String getString(String key, String defValue) {
        try {
            String value = mSharedPreferences.getString(encryptKey(key), defValue);
            if (value != null && !value.equals(defValue)) {
                return decryptValue(value);
            }
            return value;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return defValue;
    }

    /**
     * 获取Boolean
     *
     * @param key
     * @param defValue
     * @return
     */
    public boolean getBoolean(String key, boolean defValue) {
        try {
            String value = getString(key, String.valueOf(defValue));
            return Boolean.parseBoolean(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return defValue;
    }

    /**
     * 获取int
     *
     * @param key
     * @param defValue
     * @return
     */
    public int getInt(String key, int defValue) {
        try {
            String value = getString(key, String.valueOf(defValue));
            return Integer.parseInt(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return defValue;
    }

    /**
     * 获取long
     *
     * @param key
     * @param defValue
     * @return
     */
    public long getLong(String key, long defValue) {
        try {
            String value = getString(key, String.valueOf(defValue));
            return Long.parseLong(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return defValue;
    }

    /**
     * 获取Float
     *
     * @param key
     * @param defValue
     * @return
     */
    public float getFloat(String key, float defValue) {
        try {
            String value = getString(key, String.valueOf(defValue));
            return Float.parseFloat(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return defValue;
    }

    /**
     * 获取double
     *
     * @param key
     * @param defValue
     * @return
     */
    public double getDouble(String key, double defValue) {
        try {
            String value = getString(key, String.valueOf(defValue));
            return Double.parseDouble(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return defValue;
    }


    public Editor edit() {
        return new Editor(mSharedPreferences.edit());
    }

    /**
     * Editor的包装类
     */
    public class Editor {
        private SharedPreferences.Editor editor;

        private Editor(SharedPreferences.Editor editor) {
            this.editor = editor;
        }

        public Editor putString(String key, String value) {
            editor.putString(encryptKey(key), encryptValue(value));
            return this;
        }

        public Editor putInt(String key, int value) {
            putString(key, String.valueOf(value));
            return this;
        }

        public Editor putLong(String key, long value) {
            putString(key, String.valueOf(value));
            return this;
        }

        public Editor putFloat(String key, float value) {
            putString(key, String.valueOf(value));
            return this;
        }

        public Editor putDouble(String key, double value) {
            putString(key, String.valueOf(value));
            return this;
        }

        public Editor putBoolean(String key, boolean value) {
            putString(key, String.valueOf(value));
            return this;
        }


        public void apply() {
            editor.apply();
        }

        public Editor clear() {
            editor.clear();
            return this;
        }

        public Editor remove(String key) {
            editor.remove(encryptKey(key));
            return this;
        }

    }

    /**
     * 获取shared_prefs 根目录:data/data/package/shared_prefs
     *
     * @param context
     * @return
     */
    public static String getSharedPrefsRoot(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return new File(context.getDataDir(), "shared_prefs").getAbsolutePath();
        }
        return new File(context.getFilesDir().getParentFile(), "shared_prefs").getAbsolutePath();
    }

    /**
     * 清空所有SharedPreferences文件中的内容
     *
     * @param context
     */
    public static void clearAllSharedPrefs(Context context) {
        String sharedPrefsRoot = getSharedPrefsRoot(context);
        File root = new File(sharedPrefsRoot);
        if (root.exists() && root.isDirectory()) {
            String[] list = root.list();
            if (list != null) {
                for (String item : list) {
                    if (item.endsWith(".xml")) {
                        String name = item.substring(0, item.length() - 4);
                        SharedPreferences sp = context.getSharedPreferences(name, Context.MODE_PRIVATE);
                        if (sp != null) {
                            SharedPreferences.Editor edit = sp.edit();
                            edit.clear();
                            edit.apply();
                            Logger.d(TAG, "清空:" + name);
                        }
                    }
                }
            }
        }

    }


}
